"""
    基于numpy重写算法
"""
import copy
import random
import time

import numpy as np

workpiece_num = 0               #  工件数
machine_num =0                  #  机器数
data = []                       #  全局数据文件
LENGHT = 10                     #  种群长度
POPU   = []                     #  种群

def load_data(path):
    """
    加载数据文件到全局data变量中
    """
    global workpiece_num,machine_num,data
    with open(path) as file:
        lines = file.readlines()
    # 初始化工件数目，机器数目
    workpiece_num, machine_num = int(lines[0]),int(lines[1])
    for i in range(3,len(lines),3):
        id = int(lines[i].strip())                              #编号
        time = int(lines[i+1].strip())                          #延迟时间
        process_time = np.array(lines[i+2].strip().split(),dtype=int)     #加工时间
        data.append([id,time,process_time])
def init():
    """初始化种群"""
    global POPU
    POPU = [np.random.permutation(workpiece_num) for _ in range(workpiece_num)]

def decode(X):
    """
        根据解X计算甘特图参数
        [
            [['beginTime','endTime'],['beginTime','endTime'],['beginTime','endTime']],
            [['beginTime','endTime'],['beginTime','endTime'],['beginTime','endTime']]
        ]
    """
    # 甘特图需要的参数
    gantt = [[[0,0] for _ in range(workpiece_num)] for _ in range(machine_num)]
    # print(gantt)
    # 提取最后一列（时间序列）      深拷贝：避免修改data数组
    times_array = copy.deepcopy([item[-1] for item in data])
    # 按照解序列排序
    sorted_arrays = [times_array[i] for i in X]
    # 计算加工时间矩阵
    # 第一行
    sorted_arrays[0] = np.cumsum(sorted_arrays[0])
    # 其他行
    for i in range(1,workpiece_num):
        for j in range(0,machine_num):
            if j == 0:      #  如果是第一个工序，加工时间 = 该机器上一个工件的加工结束时间 + 该工序的加工时间
                sorted_arrays[i][j] += sorted_arrays[i - 1][j]
            else:           #  不是第一个工序:     max(上一个工序的加工结束时间,该机器上一个工件的加工结束时间)+ 该工序的加工时间
                sorted_arrays[i][j] = max(sorted_arrays[i-1][j],sorted_arrays[i][j-1]) + sorted_arrays[i][j]
            # gantt[i][j] = [56,sorted_arrays[i][j]]
    return np.max(sorted_arrays)

entites = []
population = []
def readFile(filename):
    global entites, workpiece_num, machine_num
    with open(filename, 'r') as file:
        # 工件个数
        workpiece_num = int(file.readline())
        # 机器个数
        machine_num = int(file.readline())
        file.readline()
        while True:
            flag = 0
            entity = {}
            for i in range(0, 3):
                line = file.readline()
                if not line:
                    flag = 1
                    break
                if i == 0:
                    continue
                if i == 1:
                    entity['delay'] = int(line.strip())
                if i == 2:
                    entity['processing_time'] = list(map(int, line.strip().split()))
            entites.append(entity)
            if flag == 1:
                break
def calculate_total_time(schedule):
    total_time = 0
    total_delay_time = 0
    delay_time = []
    for item in schedule:
        times = entites[item]['processing_time']
        curryTime = 0
        # 对于第一个工件直接相加
        if item == schedule[0]:
            for i in times:
                curryTime += i
                delay_time.append(curryTime)
        # 其他工件需要计算延迟时间
        else:
            for index, i in enumerate(times):
                # 第一个机器都会有延迟，直接加上延迟表中的第一项
                if index == 0:
                    # 更新当前时间
                    curryTime += delay_time[0] + i
                    # 更新延迟时间
                    delay_time[0] = curryTime
                else:
                    # 需要判断当前时间是否大于等于前一个工件的加工时间
                    if delay_time[index - 1] >= delay_time[index]:
                        curryTime += i
                        delay_time[index] = curryTime
                    # 否则需要加上上一个的等待时间
                    else:
                        # 时间差值
                        de = delay_time[index] - delay_time[index - 1]
                        curryTime = curryTime + de + i
                        delay_time[index] = curryTime
        # 计算延迟时间
        if delay_time[machine_num - 1] > entites[item]['delay']:
            total_delay_time += (delay_time[machine_num - 1] - entites[item]['delay'])
        # 计算总加工时间
        if delay_time[machine_num - 1] > total_time:
            total_time = delay_time[machine_num - 1]
    # print(total_time)
    return total_time, total_delay_time
def init1():
    global population,reference_point
    population = []
    random_numbers = list(range(workpiece_num))

    for i in range(0, LENGHT):
        random.shuffle(random_numbers)
        result_array = random_numbers[:workpiece_num]
        item = {}
        item['array'] = result_array
        item_time = calculate_total_time(result_array)
        # 计算总加工时间
        item['process'] = int(item_time[0])
        # 计算总延迟时间
        item['delay'] = (item_time[1])

        # 计算适应值
        item['fit'] = 0
        # flag
        item['flag'] = 0
        population.append(item)
load_data("../data/20_5_01_ta001.txt")
readFile("../data/20_5_01_ta001.txt")
init1()
init()

"""
[{'array': array([14,  7,  0, 18, 10, 13,  8,  5,  4,  6, 11,  2,  3,  1, 12, 16, 17,
       15,  9, 19]), 'flag': 0, 'fit': 3392110, 'process': 1297, 'delay': 3837}, {'array': array([14,  7,  5, 18, 10, 13,  8,  0,  4,  6, 11,  2,  3,  1, 12, 16, 17,
       15,  9, 19]), 'flag': 0, 'fit': 3392110, 'process': 1297, 'delay': 4266}, {'array': array([ 8, 13,  7, 18, 12, 14, 16,  1,  3,  6, 10,  5,  4, 11,  2,  0, 17,
       15,  9, 19]), 'flag': 0, 'fit': 3392110, 'process': 1297, 'delay': 4142}, {'array': array([ 8, 12,  3, 18,  5, 14,  0,  1,  2,  6, 10,  7,  4, 16, 13, 11, 17,
       15,  9, 19]), 'flag': 0, 'fit': 3392110, 'process': 1297, 'delay': 4381}, {'array': array([14,  5,  7, 18,  1, 13,  8,  0,  4,  6, 11,  2,  3, 10, 12, 16, 17,
       15,  9, 19]), 'flag': 0, 'fit': 3392110, 'process': 1297, 'delay': 3850}, {'array': array([14,  7,  5, 18, 13, 10,  8,  6,  4,  0, 11,  2,  3,  1, 12, 16, 17,
       15,  9, 19]), 'flag': 0, 'fit': 3392110, 'process': 1297, 'delay': 4200}, {'array': array([ 8, 13,  7, 18, 12, 14,  0,  1,  3, 16,  6,  5,  4, 11,  2, 10, 17,
       15,  9, 19]), 'flag': 0, 'fit': 3392110, 'process': 1297, 'delay': 4025}, {'array': array([14,  5,  7, 10, 18, 13,  8,  0,  4,  6, 11,  2,  3,  1, 12, 16, 17,
       15,  9, 19]), 'flag': 0, 'fit': 3392110, 'process': 1297, 'delay': 4619}, {'array': array([ 8, 13,  7, 18, 12, 14,  0,  1,  3, 10,  6,  5,  4, 11,  2, 16, 17,
       15,  9, 19]), 'flag': 0, 'fit': 3392110, 'process': 1297, 'delay': 4135}, {'array': array([ 8, 13,  7, 18, 12, 14,  0, 15,  3, 10,  6,  5, 16,  1,  2,  4, 17,
       11,  9, 19]), 'flag': 0, 'fit': 3392110, 'process': 1297, 'delay': 4435}, {'array': array([14,  7,  0, 18, 10, 13,  8,  5,  4,  6, 11,  2,  3,  1, 12, 16, 17,
"""
x = [ 8, 14,  7,  0, 18, 13, 16,  2,  5,  6, 10,  3,  1, 12,  4, 17, 15, 9, 19, 11]
print(decode(x))
print(calculate_total_time(x))
